package stancel.peter.smslogger.background;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import stancel.peter.smslogger.R;
import stancel.peter.smslogger.activities.MainActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsMessage;
import android.widget.Toast;

/**
 * Spusti sa vzdy pri prijati smsky.
 * @author Peter Stancel
 */
public class SMSBroadcastReceiver extends BroadcastReceiver {

	Context context;
	
	/**
	 * Ziskava informacie o prijatej sms (<i>time, number, text</i>),
	 * ktore posiela sluzbe <b>SMSLoggerService</b> pre dalsie vyuzitie.
	 * Taktiez, ak to pouzivatel vyzaduje (pomocou <b>SharedPreferences</b>),
	 * kontroluje, ci ma zapisat prijatu sms do suboru, vytvara oznamenie
	 * alebo vypina zvuk oznamenia prijatej sms.
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
			
	        Bundle bundle = intent.getExtras();
			if (bundle != null) {
				// ziskanie informacii o sms
				Object[] pdus = (Object[]) bundle.get("pdus");
				final SmsMessage[] messages = new SmsMessage[pdus.length];
				// ak je smska prilis dlha, je rozdelena na casti ukladane do pola messages
				for (int i = 0; i < pdus.length; i++) {
					messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
				}
				if (messages.length > -1) {
					this.context = context;
					SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
					String number = messages[0].getOriginatingAddress();
					if(!preferences.getBoolean("smslogger_preferences_set_filter", false) || checkNumber(number)){
						Calendar calendar = Calendar.getInstance();
						SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
						
						String time = simpleDateFormat.format(calendar.getTime());
						StringBuilder text = new StringBuilder();

						// casti dlhej sms sa spajaju do premennej text
						for (int i = 0; i < messages.length; i++) {
							text.append(messages[i].getMessageBody());
						}
						
						/*
						 * Nasledujuce 3 riadky ulozia sms spravu do textoveho suboru SmsLog.txt
						 * na SD kartu. Neviem ci je to podmienkou, preto som to nechal. Nemusi
						 * to tu byt, kedze tato aplikacia vyuziva ine ukladanie sprav.
						 */
						StringBuilder textLog = new StringBuilder();
						textLog.append(time + " - " + number + " - " + text.toString() + "\n");
						saveToFile(textLog);
						
						// na vypnutie zvukov oznameni inych aplikacii je potrebne
						// stlmit zvuk vsetkych oznameni pomocou AudioManagera
						AudioManager audioManager = (AudioManager) context.getSystemService(context.AUDIO_SERVICE);
						boolean notificationSound = preferences.getBoolean("smslogger_preferences_set_mute", true);
				        audioManager.setStreamMute(AudioManager.STREAM_NOTIFICATION, !notificationSound);
						if(preferences.getBoolean("smslogger_preferences_set_notification", true)){
							// vytvori oznamenie o prijatej SMS
							NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
							Notification notification = new Notification(R.drawable.icon, context.getString(R.string.new_sms), System.currentTimeMillis());
							PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
									new Intent(context, MainActivity.class), 0);
							notification.setLatestEventInfo(context, context.getString(R.string.app_name),
									context.getString(R.string.latest_sms), pendingIntent);
							notification.flags = Notification.FLAG_AUTO_CANCEL;
							if(notificationSound){
								notification.defaults = Notification.DEFAULT_SOUND;
							}
							notificationManager.notify(11223, notification);
						}

						// poslanie informacii sluzbe
						Bundle bundleSms = new Bundle();
						bundleSms.putString("sms_time", time);
						bundleSms.putString("sms_number", number);
						bundleSms.putString("sms_text", text.toString());
						
						// vytvorenie sluzby pre ulozenie sms spravy do suborov
						Intent serviceIntent = new Intent(context, SMSLoggerService.class);
						serviceIntent.putExtras(bundleSms);
						context.startService(serviceIntent);
					}
				}
			}
		}
	}

	/**
	 * Zapise informacie o prijatej sms do suboru "SmsLog.txt", ktory sa nachadza
	 * na SD karte. Ak sa v zariadeni nenachadza SD karta, vypise o tom spravu. 
	 * @param textLog Informacie o prijatej sms.
	 */
	private void saveToFile(StringBuilder textLog) {
		try {
			File file = new File(Environment.getExternalStorageDirectory(), "SmsLogger");
			File fileOutput = new File(file, "SmsLog.txt");
			file.mkdir();
			
			BufferedWriter buf = new BufferedWriter(new FileWriter(fileOutput, true)); 
		    buf.append(textLog);
		    buf.flush();
		    buf.close();
		} catch (FileNotFoundException e) {
			// Subor neexistuje.
			// Moze to nastat ak sa spusti aplikacia prvykrat.
		} catch (IOException e) {
			Toast.makeText(context, R.string.error_external_storage, Toast.LENGTH_SHORT).show();
		}
	}
	
	/**
	 * Zisti, ci sa <i>number</i> nachadza v subore "SmsFilter.txt", ktory sa nachadza
	 * na SD karte. Ak sa v zariadeni nenachadza SD karta, vypise o tom spravu. 
	 * @param number Cislo prijatej sms.
	 * @return true ak sa <i>number</i> nachadza v subore "SmsFilter.txt", inak false
	 */
	private boolean checkNumber(String number) {
		try {
			File file = new File(Environment.getExternalStorageDirectory(), "SmsLogger");
			File fileOutput = new File(file, "SmsFilter.txt");
			file.mkdir();
			
			BufferedReader buf = new BufferedReader(new FileReader(fileOutput));
			String line;
			while((line = buf.readLine()) != null){
				if(PhoneNumberUtils.compare(number, line)){
					return true;
				}
			}
		    buf.close();
		} catch (FileNotFoundException e) {
			// Subor neexistuje.
			// Moze to nastat ak sa spusti aplikacia prvykrat.
		} catch (IOException e) {
			Toast.makeText(context, R.string.error_external_storage, Toast.LENGTH_SHORT).show();
		}
		return false;
	}
}